class StockChoiceJob
  include Sidekiq::Worker
  sidekiq_options :queue => :stock_choice, :retry => false

  # 自选股 job
  # 交易日每分钟执行一次
  def perform(alert_message)
    logger.info alert_message
    Stock.where(is_choice: true).sort_by{|x| x.choice_at}.reverse.first(60).each do |stock|
      if trade_time
        today = JSON.parse $Redis.get(stock["symbol"])
        today["buy_change"] = cul_change(stock.buy_price, today["trade"])
        today["sell_change"] = cul_change(stock.sell_price, today["trade"])
        hs_ths_flow = RealTime.hs_ths_flow stock.symbol # 交易日每分钟执行一次
        stock.update(ths_flow: hs_ths_flow["title"]["je"], score: hs_ths_flow["score"])
        next if stock.is_alert && Time.now.strftime("%M").to_i % 8 != 0 # 如果已经告警过，并且当前分钟不是 8 的倍数，则跳过
        content = <<~MD
          ** stock_choice_job ***
          > #{stock.symbol} -- #{stock.name}
          > [编辑](https://wyyzrx.com/admin/stocks/#{stock.id})  
          > 120.53.3.4/admin/stocks/#{stock.id} 
          > 当前: #{today["trade"].to_f.round(2)}
          > 涨幅: #{today["changepercent"]}%  
          > 买卖价: #{stock.buy_price} -- #{stock.sell_price}
          > 资流:  #{hs_ths_flow["title"]["je"].to_f > 0 ? "↑" : "↓"} #{hs_ths_flow["title"]["je"]}
        MD

        if stock.ma_alert.present?
          ma = stock.ma_alert.abs
          trade_date_x = trade_date ma
          get_k_data = Tushare::Stock::Trading.get_k_data(stock.symbol, "#{trade_date_x[0..3]}-#{trade_date_x[4..5]}-#{trade_date_x[6..7]}", Time.now.strftime("%Y-%m-%d"))
          arr_x = get_k_data.map { |x| x["close"] } << today["trade"].to_f
          ma_x = (arr_x.sum / arr_x.size).round(2)
          # 如果当前价小于或大于均线
          if (stock.ma_alert < 0 && today["trade"].to_f < ma_x) || (stock.ma_alert > 0 && today["trade"].to_f > ma_x)
            vch = today_volume stock.symbol
            stock.update(is_alert: true, volume_change: vch)
            stock.update(note: "当前价 #{stock.ma_alert < 0 ? '<' : '>'} #{ma}日均线")
            content << <<~MD
              > #{ma}日均线: #{ma_x}
              > 同量: #{vch}
              > 告警原因："当前价 #{stock.ma_alert < 0 ? '<' : '>'} #{ma}日均线
            MD
            Robot.zhangchunhua(content)
            Time.now.day > 15 ? (Robot.dd_choice_ai content) : (Robot.dd_choice content)
          end
        end
        # 如果当前价小于等于买入价
        if stock.buy_price.present? && today["trade"].to_f <= stock.buy_price.to_f
          vch = today_volume stock.symbol
          stock.update(is_alert: true, volume_change: vch)
          stock.update(note: "低于目标价 #{stock.buy_price}")
          content << <<~MD
              > 同量: #{vch}
              > 告警原因：低于目标价 #{stock.buy_price} 
          MD
          Robot.zhangchunhua content
          Time.now.day > 15 ? (Robot.dd_choice_ai content) : (Robot.dd_choice content)
        end
        # 如果当前价大于等于卖出价
        if stock.sell_price.present? && today["trade"].to_f >= stock.sell_price.to_f
          vch = today_volume stock.symbol
          stock.update(is_alert: true, volume_change: vch)
          stock.update(note: "突破目标价 #{stock.sell_price}")
          content << <<~MD
              > 同量: #{vch}
              > 告警原因：突破目标价 #{stock.sell_price}
          MD
          Robot.zhangchunhua content
          Time.now.day > 15 ? (Robot.dd_choice_ai content) : (Robot.dd_choice content)
        end
      else
        logger.info "非交易时间"
      end
    end
  end
end

def to_sina_code(code)
  return %w(5 6 9).include?(code.to_s[0]) ? "sh#{code}" : "sz#{code}" if code.size == 6
  code[-2..-1].downcase + code[0..5] if code[6] == "."
end

def trade_date(x)
  days = x < 10 ? x + 20 : x * 2.3
  sse = $TusharePro.tushare_pro("trade_cal", "exchange": "SSE", "start_date": (Time.now - days.day).strftime("%Y%m%d"), "end_date": (Time.now).strftime("%Y%m%d")).select { |sse| sse["is_open"] == 1 }
  sse[x - 1]["cal_date"]
end

def trade_time
  Time.current.between?(Time.current.change(hour: 9, min: 30), Time.current.change(hour: 11, min: 31)) || Time.current.between?(Time.current.change(hour: 13, min: 00), Time.current.change(hour: 15, min: 01))
end

def cul_change(open, close)
  ((close.to_f - open.to_f) * 100 / open.to_f).round(2)
end

def today_volume(code)
  today = "#{trade_date(1)[0, 4]}-#{trade_date(1)[4, 2]}-#{trade_date(1)[6, 2]}"
  yesterday = "#{trade_date(2)[0, 4]}-#{trade_date(2)[4, 2]}-#{trade_date(2)[6, 2]}"

  kline = RealTime.hs_kline to_sina_code(code)
  today_5min = kline.select { |x| x["day"].split(" ")[0] == today }
  yesterday_5min = kline.select { |x| x["day"].split(" ")[0] == yesterday }.first(today_5min.count)

  today_volume = today_5min.pluck("volume").sum { |x| x.to_f }
  yes_volume = yesterday_5min.pluck("volume").sum { |x| x.to_f }
  (today_volume / yes_volume).round(2) if yes_volume != 0
end